import 'dart:math';

import 'package:flutter/material.dart';
import 'package:hc_ui/utils/hc_number_util.dart';

///角度转换后的类
class HcGradientAliment {
  Alignment begin;
  Alignment end;

  HcGradientAliment(
      {this.begin = Alignment.topCenter, this.end = Alignment.bottomCenter});

  @override
  String toString() {
    // TODO: implement toString
    return 'begin:$begin,end:$end';
  }
}

class HcGradientUtil {
  const HcGradientUtil._();

  ///将角度转换成需要的起始位置
  ///[degree] 旋转的角度
  ///[lineWidthThick] 每段宽度
  ///[lineHeightThick] 每段高度
  static HcGradientAliment formatDegree2Aliment(
      {required double degree, lineWidthThick = 1, lineHeightThick = 1}) {
    HcGradientAliment gradientAliment = HcGradientAliment();
    //避免0/0的情况
    degree = degree == 0 ? 360 : degree;
    //将角度转换成0-360;
    degree = (degree + 360) % 360;
    //将角度变成-180-180
    degree = degree > 180 ? degree - 360 : degree;
    //0,90,180,270,360 tan值为0
    //获取y=kx+b中的k 斜率
    double k = degree % 90 == 0 ? 0 : tan(HcNumberUtil.degree2radians(degree));
    //角度与角度绝对值的比为正表示在坐标轴右侧 否则在左侧
    //计算方法 y=tanA*x;
    //如果角度在(0-180]度时,起始角度的X轴为[-1,0];
    double tempX = HcNumberUtil.formatNumber(-(degree / degree.abs()));
    // 勾股定理 计算当X轴(角度为负的时候取1,角度为正的时候取-1 )的时候Y轴参数
    //计算方法 y=tanA*x;
    // 因为Aliment坐标轴Y轴顶端为-1与正常的坐标轴相反所以要*-1
    double startY = -HcNumberUtil.formatNumber(tempX * k);
    //计算当Y轴等于1的时候X轴所在位置
    // x=y/tanA;
    //当前角度的绝对值大于90度的 时候y轴坐落在(0,1]之间
    double tempY = (degree.abs() > 90 ? 1 : -1);
    double startX = k == 0 ? 0 : HcNumberUtil.formatNumber(tempY / k);
    // startX = startX.abs() == double.infinity ? 0 : startX;
    //当startY超过1的时候表示x取1的时候 y的值越界所以只能取startX的值
    //当startX超过1的时候表示y取1的时候x越界 所以取startY的值
    if (degree % 180 == 0 || degree != 90 && startX.abs() <= 1) {
      gradientAliment.begin = Alignment(startX, -tempY);
    } else {
      gradientAliment.begin = Alignment(tempX, startY);
    }

    //结束的角度与初始角度呈中心对称
    gradientAliment.end = Alignment(
        -gradientAliment.begin.x * (lineWidthThick * 2 - 1),
        -gradientAliment.begin.y * (lineHeightThick * 2 - 1));
    return gradientAliment;
  }

  /// 构建分割符的虚线
  /// [color] 颜色
  /// [isVertical] 是否是纵向的
  static LinearGradient generateDividerDashed(
      {required color, required bool isVertical, int? dashedCounts}) {
    return generateLinearGradient(
      colors: [color, Colors.transparent],
      stops: [0.5, 0.5],
      degree: isVertical ? 0 : 90,
      tileMode: TileMode.repeated,
      width: isVertical
          ? 1
          : dashedCounts != null
              ? (1 / dashedCounts)
              : 0.08,
      height: !isVertical
          ? 1
          : dashedCounts != null
              ? (1 / dashedCounts)
              : 0.4,
    );
  }

  ///构建线性渐变背景
  ///[color] 颜色
  ///[degree] 角度
  ///[lineThick] 每段宽度(所占总长度的百分比小数)
  ///构建线性渐变背景
  ///[color] 颜色
  ///[degree] 角度
  ///[lineThick] 每段宽度
  static LinearGradient generateStripesBckGround(
      {required Color color, double degree = 225, double lineThick = 0.07}) {
    List<Color> colorList = List.empty(growable: true);
    for (int i = 0; i < 7; i++) {
      if (i == 0 || i == 3 || i == 4) {
        colorList.add(color.withOpacity(0.5));
      } else {
        colorList.add(Colors.transparent);
      }
    }
    return generateLinearGradient(
        degree: degree,
        tileMode: TileMode.repeated,
        colors: colorList,
        stops: [0.1, 0, 0.5, 0, 0.6, 0, 1],
        width: lineThick,
        height: lineThick);
  }

  static LinearGradient generateDashedLine({
    required Color color,
    double width = 0.1,
  }) {
    return generateLinearGradient(
        colors: [color, Colors.transparent],
        stops: [0.5, 0],
        degree: 90,
        tileMode: TileMode.repeated,
        width: width);
  }

  /// 构建线性渐变
  /// [degree] 旋转角度
  /// [colors] 颜色组
  /// [stops] 数组长度需要和颜色保持一致 否则不设置
  /// [width] 线段宽度 总宽度的倍数
  /// [height] 线段长度 总长度的倍数
  /// [tileMode] 重复模式 CLAMP 边缘颜色 repeated重复  mirror镜像
  static LinearGradient generateLinearGradient(
      {double degree = 90,
      required List<Color> colors,
      List<double>? stops,
      double width = 1,
      double height = 1,
      tileMode = TileMode.clamp,
      GradientTransform? transform}) {
    stops = stops?.length == colors.length ? stops : null;
    HcGradientAliment aliment = formatDegree2Aliment(
        degree: degree, lineWidthThick: width, lineHeightThick: height);
    return LinearGradient(
        colors: colors,
        stops: stops,
        begin: aliment.begin,
        end: aliment.end,
        tileMode: tileMode,
        transform: transform);
  }
}
